#include "BulgeRender.h"
#include <cassert>

BulgeRender::BulgeRender(const std::string& name) :IRender(name)
{
	mHandleBulgeVertex = ShaderManager::Instance()->CreateShader(SID_SAMPLE_14_VERTEX);
	ShaderManager::Instance()->LoadShader(mHandleBulgeVertex);

	glPushMatrix();

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(2.2, 1, 0.2);
	glRotatef(70, 1, 1, 1);
	glGetFloatv(GL_MODELVIEW_MATRIX, mModelMatrixSphere);

	glLoadIdentity();
	glTranslatef(-2, -1.5, 0);
	glRotatef(-55, 1, 0, 0);
	glGetFloatv(GL_MODELVIEW_MATRIX, mModelMatrixTorus);

	glLoadIdentity();
	gluLookAt(0, 0, 13, 0, 0, 0, 0, 1, 0);
	glGetFloatv(GL_MODELVIEW_MATRIX, mViewMatrix);

	float projectMatrix[16];

	glLoadIdentity();
	gluPerspective(40, 1, 1, 20);
	glGetFloatv(GL_MODELVIEW_MATRIX, projectMatrix);

	glLoadIdentity();
	glLoadMatrixf(projectMatrix);
	glMultMatrixf(mViewMatrix);
	glMultMatrixf(mModelMatrixSphere);
	glGetFloatv(GL_MODELVIEW_MATRIX, mSphereMVP);

	glLoadIdentity();
	glLoadMatrixf(projectMatrix);
	glMultMatrixf(mViewMatrix);
	glMultMatrixf(mModelMatrixTorus);
	glGetFloatv(GL_MODELVIEW_MATRIX, mTorusMVP);

	glPopMatrix();

	mTorusKd[0] = 0.8; mTorusKd[1] = 0.1; mTorusKd[2] = 0.1; mTorusKd[3] = 1;
	mSphereKd[0] = 0.1; mSphereKd[1] = 0.7; mSphereKd[2] = 0.1; mSphereKd[3] = 1;

	mTime = 0.0f;
	mTimeFlow = 0.01f;
	glViewport(0, 0, 400, 400);
	glClearColor(0.1, 0.1, 0.5, 0);
}

BulgeRender::~BulgeRender()
{

}

void BulgeRender::idle()
{
	/* Repeatedly advance and rewind time. */
	if (mTime > 10) {
		mTime = 10;
		mTimeFlow = -mTimeFlow;
	}
	else if (mTime < 0) {
		mTime = 0;
		mTimeFlow = -mTimeFlow;
	}
	mTime += mTimeFlow;  /* Add time delta. */
}

void BulgeRender::draw()
{
	ShaderManager::Instance()->BindShader(mHandleBulgeVertex);
	ShaderManager::Instance()->EnableShaderProfile(mHandleBulgeVertex);

	CGprogram vertexProgram = ShaderManager::Instance()->GetProgram(mHandleBulgeVertex);
	CGparameter lightColor = cgGetNamedParameter(vertexProgram, "light.color");
	CGparameter lightPosition = cgGetNamedParameter(vertexProgram, "light.position");
	CGparameter shiness = cgGetNamedParameter(vertexProgram, "light.shiness");
	CGparameter eyePosition = cgGetNamedParameter(vertexProgram, "eyePosition");
	CGparameter scaleFactor = cgGetNamedParameter(vertexProgram, "scaleFactor");
	CGparameter frequency = cgGetNamedParameter(vertexProgram, "frequency");
	CGparameter time = cgGetNamedParameter(vertexProgram, "time");

	cgSetParameter3f(lightColor, 0.95f, 0.95f, 0.95f);
	cgSetParameter3f(lightPosition, 5 * sin(-0.4), 1.5, 5 * cos(-0.4));
	cgSetParameter3f(eyePosition, 0, 0, 13);
	cgSetParameter1f(shiness, 35);
	cgSetParameter1f(scaleFactor, 0.3);
	cgSetParameter1f(frequency, 2.4);
	cgSetParameter1f(time, 0);
	
	CGparameter kd = cgGetNamedParameter(vertexProgram, "kd");
	CGparameter modelMatrix = cgGetNamedParameter(vertexProgram, "modelMatrix");
	CGparameter mvp = cgGetNamedParameter(vertexProgram, "mvp");

	/*** Render green solid bulging sphere ***/
	cgSetMatrixParameterfr(modelMatrix, mModelMatrixSphere);
	cgSetMatrixParameterfr(mvp, mSphereMVP);
	cgSetParameter4f(kd, mSphereKd[0], mSphereKd[1], mSphereKd[2], mSphereKd[3]);
	cgUpdateProgramParameters(vertexProgram);
	glutSolidSphere(1.0, 40, 40);

	/*** Render red solid bulging torus ***/
	cgSetMatrixParameterfr(modelMatrix, mModelMatrixTorus);
	cgSetMatrixParameterfr(mvp, mTorusMVP);
	cgSetParameter4f(kd, mTorusKd[0], mTorusKd[1], mTorusKd[2], mTorusKd[3]);
	cgUpdateProgramParameters(vertexProgram);
	glutSolidTorus(0.15, 1.7, 40, 40);

	ShaderManager::Instance()->DisableShaderProfile(mHandleBulgeVertex);
	ShaderManager::Instance()->UnBindShader(mHandleBulgeVertex);
}